﻿// Copyright (c) Vitaly Kamiansky. All rights reserved. 
// See License.txt in the project root.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Property.Timers
{
    public partial class PortableTimerPrototype
    {
        private class TimerInstance : ITimer
        {
            public TimerInstance(TimeSpan interval)
            {
                _Interval = interval;
            }

            private readonly TimeSpan _Interval;
            public TimeSpan Interval { get { return _Interval; } }

            private CancellationTokenSource CancelSourceState;
            private Task TimerTaskState;

            public async void Start()
            {
                if (TimerTaskState != null && TimerTaskState.Status == TaskStatus.Running) return;
                var token = (CancelSourceState = new CancellationTokenSource()).Token;
                while (!token.IsCancellationRequested)
                {
                    await Task.WhenAny((TimerTaskState = Task.Delay(_Interval, token)),Task.Factory.StartNew(()=>
                        {
                            while (!token.IsCancellationRequested) { }
                        }));
                    if (!token.IsCancellationRequested) OnTick();
                }
            }

            public void Stop()
            {
                if (CancelSourceState == null) return;

                CancelSourceState.Cancel(false);
                CancelSourceState.Dispose();
                CancelSourceState = null;
            }

            public event EventHandler Tick;
            private void OnTick()
            {
                if (Tick == null) return;

                Tick(this, new EventArgs());
            }

            public void Dispose()
            {
                Stop();
            }
        }
    }
}
